#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
战争数据处理系统
War Data Processing System
=========================
功能：从Excel格式的战争历史数据中提取结构化信息，生成标准化JSON数据
支持：单文件处理、批量处理、数据统计分析、质量评估
作者：Data Processing Engine
版本：1.0
日期：2025年
依赖：pandas, openpyxl, xlrd
"""

import pandas as pd
import json
import re
from pathlib import Path
import os
import traceback
from datetime import datetime


def extract_war_data_from_text(war_desc, time_info):
    """
    从战争描述文本中智能提取关键信息

    参数:
        war_desc (str): 战争描述原文
        time_info (str): 战争时间相关信息（如【起始年】字段）

    返回:
        dict: 包含年份、地点、交战双方、性质、持续时间的字典
    """
    # 处理空值情况
    if pd.isna(war_desc):
        war_desc = ""
    if pd.isna(time_info):
        time_info = ""

    # 合并所有文本信息用于提取
    full_text = str(war_desc).strip() + " " + str(time_info).strip()

    # ----------------------
    # 1. 提取年份信息
    # ----------------------
    year = None
    # 支持多种年份格式：【起始年】前206年、前771年、1900年、1900-1910年等
    year_patterns = [
        # 匹配【起始年】前206年 乙未 汉高帝元年 格式
        r'【起始年】\s*([前前]?\d{3,4})\s*年',
        # 匹配前206年、1900年格式
        r'\b([前前]?\d{3,4})\s*年\b',
        # 匹配1900-1910年格式（取起始年）
        r'\b(\d{4})\s*[-–—]\s*\d{4}\s*年\b',
        # 匹配单纯数字年份（如206 BC会被处理为-206）
        r'\b(\d{3,4})\s*BC\b'
    ]

    for pattern in year_patterns:
        match = re.search(pattern, full_text, re.IGNORECASE)
        if match:
            year_str = match.group(1).strip()
            try:
                # 处理公元前年份（转换为负数）
                if '前' in year_str or '前' in year_str or 'BC' in full_text.upper():
                    year_num = int(re.sub(r'[前前]', '', year_str))
                    year = -year_num
                else:
                    year = int(year_str)
                break
            except (ValueError, TypeError):
                continue

    # ----------------------
    # 2. 提取地点信息
    # ----------------------
    location = None
    location_patterns = [
        # 匹配【相关地点】后的内容
        r'【相关地点】\s*([^【】\n]+)',
        # 匹配地点：北京 格式
        r'地点[:：]\s*([^，。\n；]+)',
        # 匹配"于某地发生"、"在某地进行"格式
        r'[于在]\s*([^，。\n；]+)\s*[发生进行爆发展开]',
        # 匹配明确的地名（如北京、咸阳、骊山）
        r'\b([京津沪渝冀豫云辽黑湘皖闽鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]\w{1,4}|'
        r'西安|咸阳|洛阳|长安|建康|临安|大都|燕京|北平|南京|开封|杭州|成都|'
        r'骊山|赤壁|官渡|淝水|长城|黄河|长江)\b'
    ]

    for pattern in location_patterns:
        match = re.search(pattern, full_text)
        if match and match.group(1).strip():
            location = match.group(1).strip()
            # 清理地点字符串中的多余符号
            location = re.sub(r'[，。；：""\'\'\[\]]', '', location)
            break

    # ----------------------
    # 3. 提取交战双方信息
    # ----------------------
    parties = None
    parties_patterns = [
        # 匹配【交战双方】后的内容
        r'【交战双方】\s*([^【】\n]+)',
        # 匹配双方：A与B 格式
        r'双方[:：]\s*([^，。\n；]+)',
        # 匹配"A进攻B"、"B对抗A"格式
        r'([^，。\n；]{2,8})\s*[进攻攻打对抗讨伐征伐防御反击]\s*([^，。\n；]{2,8})',
        # 匹配"A与B交战"格式
        r'([^，。\n；]{2,8})\s*[与和同]\s*([^，。\n；]{2,8})\s*[交战作战对抗]'
    ]

    for pattern in parties_patterns:
        match = re.search(pattern, full_text)
        if match:
            if len(match.groups()) == 2:
                # 处理"A进攻B"这种双组匹配
                parties = f"{match.group(1).strip()} vs {match.group(2).strip()}"
            else:
                parties = match.group(1).strip()
            # 清理交战双方字符串
            parties = re.sub(r'[，。；：""\'\'\[\]]', '', parties)
            break

    # ----------------------
    # 4. 提取战争性质信息
    # ----------------------
    nature = None
    nature_patterns = [
        # 匹配【性质】后的内容
        r'【性质】\s*([^【】\n]+)',
        # 匹配性质：领地争夺 格式
        r'性质[:：]\s*([^，。\n；]+)',
        # 匹配常见战争性质关键词
        r'属\s*([^，。\n；]+)\s*战争',
        r'\b(领地争夺|统一战争|民族冲突|农民起义|王朝更替|对外征伐|防御战争|'
        r'部落冲突|诸侯争霸|反侵略|叛乱平定|宫廷政变|割据战争)\b'
    ]

    for pattern in nature_patterns:
        match = re.search(pattern, full_text)
        if match and match.group(1).strip():
            nature = match.group(1).strip()
            break

    # ----------------------
    # 5. 提取持续时间信息
    # ----------------------
    duration = None
    duration_patterns = [
        # 匹配【时长】后的内容
        r'【时长】\s*([^【】\n]+)',
        # 匹配时长：3年 格式
        r'时长[:：]\s*([^，。\n；]+)',
        # 匹配"持续3年"、"历时5个月"格式
        r'[持续历时]\s*([^，。\n；]+)',
        # 匹配具体时长描述
        r'\b(\d+年|\d+个月|数载|数月|数年|短期|长期|短暂|持久)\b'
    ]

    for pattern in duration_patterns:
        match = re.search(pattern, full_text)
        if match and match.group(1).strip():
            duration = match.group(1).strip()
            break

    return {
        'year': year,
        'location': location,
        'parties': parties,
        'nature': nature,
        'duration': duration
    }


def extract_war_data_from_excel(file_path, all_sheets=True):
    """
    从战争Excel文件中提取结构化数据

    参数:
        file_path (str): Excel文件完整路径
        all_sheets (bool): 是否处理所有sheet，True=处理所有，False=只处理"总战争"

    返回:
        list: 包含所有战争记录的列表，每个记录为dict
    """
    try:
        # 验证文件存在性
        if not os.path.exists(file_path):
            print(f"❌ 错误：文件不存在 - {file_path}")
            return []

        # 记录开始时间
        start_time = datetime.now()
        print(f"📋 开始处理文件：{os.path.basename(file_path)}")
        print(f"⏰ 开始时间：{start_time.strftime('%Y-%m-%d %H:%M:%S')}")

        # 读取Excel文件
        excel_file = pd.ExcelFile(file_path)
        all_data = []

        # 确定要处理的sheets
        if all_sheets:
            sheets_to_process = excel_file.sheet_names
        else:
            sheets_to_process = ['总战争'] if '总战争' in excel_file.sheet_names else excel_file.sheet_names

        # 处理每个sheet
        for sheet_idx, sheet_name in enumerate(sheets_to_process, 1):
            print(f"\n📄 处理Sheet {sheet_idx}/{len(sheets_to_process)}: {sheet_name}")

            try:
                # 读取sheet数据（不设置header，手动处理）
                df = pd.read_excel(file_path, sheet_name=sheet_name, header=None)
                print(f"   🔍 数据规模：{df.shape[0]} 行 x {df.shape[1]} 列")

                # 跳过空sheet
                if df.empty:
                    print(f"   ⚠️  该Sheet为空，跳过处理")
                    continue

                # 识别并跳过标题行
                df_data = df.copy()
                first_row = df.iloc[0]
                # 判断第一行是否为标题行的条件
                header_indicators = [
                    str(first_row.iloc[0]).strip() in ['时期', '朝代', '年代'],
                    str(first_row.iloc[1]).strip() in ['战争名称', '三级', '事件名称'],
                    str(first_row.iloc[2]).strip() in ['战争描述原文', '描述', '详情']
                ]

                if sum(header_indicators) >= 2:  # 满足2个以上条件则认为是标题行
                    df_data = df.iloc[1:].reset_index(drop=True)
                    print(f"   ✅ 已识别并跳过标题行")

                # 处理每一行数据
                valid_records = 0
                for row_idx, row in df_data.iterrows():
                    # 确保至少有3列数据（时期、名称、描述）
                    if len(row) < 3:
                        continue

                    # 提取基础信息（基于列位置，兼容不同Excel格式）
                    period = row.iloc[0] if not pd.isna(row.iloc[0]) else None
                    war_name = row.iloc[1] if not pd.isna(row.iloc[1]) else None
                    war_desc = row.iloc[2] if not pd.isna(row.iloc[2]) else None
                    source = row.iloc[3] if len(row) > 3 and not pd.isna(row.iloc[3]) else None
                    time_info = row.iloc[4] if len(row) > 4 and not pd.isna(row.iloc[4]) else None
                    location_from_col = row.iloc[5] if len(row) > 5 and not pd.isna(row.iloc[5]) else None
                    parties_from_col = row.iloc[6] if len(row) > 6 and not pd.isna(row.iloc[6]) else None

                    # 过滤无效记录（至少需要时期和描述）
                    if not (period and war_desc and str(war_desc).strip()):
                        continue

                    # 从文本中提取详细信息
                    detailed_info = extract_war_data_from_text(war_desc, time_info)

                    # 优先使用列中直接提供的地点和交战双方信息
                    if location_from_col and str(location_from_col).strip():
                        detailed_info['location'] = str(location_from_col).strip()
                    if parties_from_col and str(parties_from_col).strip():
                        detailed_info['parties'] = str(parties_from_col).strip()

                    # 构建完整的战争记录
                    war_record = {
                        'category': str(period).strip(),  # 时期/朝代
                        'sheet_name': sheet_name,  # 数据来源sheet
                        'war_name': str(war_name).strip() if (war_name and str(war_name).strip()) else None,
                        'year': detailed_info['year'],  # 年份（公元前为负数）
                        'location': detailed_info['location'],  # 地点
                        'parties': detailed_info['parties'],  # 交战双方
                        'nature': detailed_info['nature'],  # 战争性质
                        'duration': detailed_info['duration'],  # 持续时间
                        'source': str(source).strip() if (source and str(source).strip()) else None,  # 文献出处
                        'original_description': str(war_desc).strip(),  # 原始描述
                        'extracted_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 提取时间
                    }

                    # 添加到结果列表
                    all_data.append(war_record)
                    valid_records += 1

                print(f"   ✅ 成功提取 {valid_records} 条有效记录")

            except Exception as sheet_e:
                print(f"   ❌ Sheet处理出错：{str(sheet_e)}")
                traceback.print_exc()
                continue

        # 计算处理时间
        processing_time = (datetime.now() - start_time).total_seconds()
        print(f"\n🎉 文件处理完成！")
        print(f"📊 总计提取记录：{len(all_data)} 条")
        print(f"⏱️  处理耗时：{processing_time:.2f} 秒")

        return all_data

    except Exception as e:
        print(f"❌ 文件读取总错误：{str(e)}")
        traceback.print_exc()
        return []


def save_war_data_to_json(data, output_file, indent=2):
    """
    将战争数据保存为JSON文件，确保中文正常显示

    参数:
        data (list): 战争数据列表
        output_file (str): 输出文件路径
        indent (int): JSON缩进空格数

    返回:
        bool: 保存成功返回True，失败返回False
    """
    try:
        # 创建输出目录（如果不存在）
        output_dir = Path(output_file).parent
        output_dir.mkdir(parents=True, exist_ok=True)

        # 保存JSON文件（使用utf-8编码，确保中文正常显示）
        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=indent, default=str)

        # 验证文件是否成功创建
        if os.path.exists(output_file) and os.path.getsize(output_file) > 0:
            file_size = os.path.getsize(output_file) / 1024  # 转换为KB
            print(f"💾 数据已成功保存到：{output_file}")
            print(f"   📁 文件大小：{file_size:.2f} KB")
            return True
        else:
            print(f"❌ 保存失败：文件创建后为空或不存在")
            return False

    except Exception as e:
        print(f"❌ 保存JSON文件出错：{str(e)}")
        traceback.print_exc()
        return False


def analyze_war_data_quality(data):
    """
    分析战争数据质量，生成详细的统计报告

    参数:
        data (list): 战争数据列表

    返回:
        dict: 包含各项质量指标的统计结果
    """
    if not data:
        print("⚠️  没有可分析的数据")
        return {}

    total_records = len(data)
    stats = {
        'total_records': total_records,
        'analysis_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'completeness': {},
        'period_distribution': {},
        'sheet_contribution': {},
        'time_coverage': {}
    }

    print("\n" + "=" * 80)
    print("📊 战争数据质量分析报告")
    print("=" * 80)

    # ----------------------
    # 1. 数据完整性统计
    # ----------------------
    fields_to_check = ['year', 'location', 'parties', 'nature', 'duration', 'source']
    completeness = {}

    for field in fields_to_check:
        count = sum(1 for record in data if record.get(field) is not None)
        rate = (count / total_records) * 100
        completeness[field] = {
            'count': count,
            'completeness_rate': round(rate, 2)
        }

    stats['completeness'] = completeness

    print("\n1. 数据完整性统计（非空字段比例）:")
    print("-" * 50)
    for field, info in completeness.items():
        field_name_map = {
            'year': '年份信息',
            'location': '地点信息',
            'parties': '交战双方',
            'nature': '战争性质',
            'duration': '持续时间',
            'source': '文献出处'
        }
        field_name = field_name_map.get(field, field)
        print(f"   {field_name:8s}: {info['count']:4d} 条 ({info['completeness_rate']:5.1f}%)")

    # ----------------------
    # 2. 时期分布统计
    # ----------------------
    period_dist = {}
    for record in data:
        period = record.get('category', '未知时期')
        period_dist[period] = period_dist.get(period, 0) + 1

    # 按记录数排序
    sorted_periods = sorted(period_dist.items(), key=lambda x: x[1], reverse=True)
    stats['period_distribution'] = dict(sorted_periods)

    print("\n2. 各历史时期战争分布:")
    print("-" * 50)
    for period, count in sorted_periods[:10]:  # 显示前10个时期
        percentage = (count / total_records) * 100
        print(f"   {period:10s}: {count:4d} 条 ({percentage:5.1f}%)")
    if len(sorted_periods) > 10:
        print(f"   ... 还有 {len(sorted_periods) - 10} 个时期未显示")

    # ----------------------
    # 3. Sheet贡献统计
    # ----------------------
    sheet_contrib = {}
    for record in data:
        sheet = record.get('sheet_name', '未知Sheet')
        sheet_contrib[sheet] = sheet_contrib.get(sheet, 0) + 1

    stats['sheet_contribution'] = sheet_contrib

    print("\n3. 各Sheet数据贡献:")
    print("-" * 50)
    for sheet, count in sorted(sheet_contrib.items(), key=lambda x: x[1], reverse=True):
        percentage = (count / total_records) * 100
        print(f"   {sheet:12s}: {count:4d} 条 ({percentage:5.1f}%)")

    # ----------------------
    # 4. 时间覆盖范围
    # ----------------------
    time_coverage = {}
    years = [record['year'] for record in data if record.get('year') is not None]

    if years:
        time_coverage['earliest_year'] = min(years)
        time_coverage['latest_year'] = max(years)
        time_coverage['year_count'] = len(years)
        time_coverage['time_span'] = time_coverage['latest_year'] - time_coverage['earliest_year']

        # 转换为公元纪年显示
        earliest_display = f"公元前{abs(time_coverage['earliest_year'])}年" if time_coverage[
                                                                                   'earliest_year'] < 0 else f"{time_coverage['earliest_year']}年"
        latest_display = f"公元前{abs(time_coverage['latest_year'])}年" if time_coverage[
                                                                               'latest_year'] < 0 else f"{time_coverage['latest_year']}年"

        print("\n4. 时间覆盖范围:")
        print("-" * 50)
        print(f"   最早战争: {earliest_display}")
        print(f"   最晚战争: {latest_display}")
        print(f"   时间跨度: {time_coverage['time_span']} 年")
        print(f"   有年份记录: {time_coverage['year_count']} 条")

    stats['time_coverage'] = time_coverage

    # ----------------------
    # 5. 整体质量评分
    # ----------------------
    # 计算平均完整性得分
    avg_completeness = sum(info['completeness_rate'] for info in completeness.values()) / len(completeness)
    data_quality_score = min(100, round(avg_completeness, 1))

    print("\n5. 整体数据质量评估:")
    print("-" * 50)
    print(f"   数据质量得分: {data_quality_score:.1f} / 100.0")

    if data_quality_score >= 90:
        quality_level = "优秀"
        quality_desc = "数据完整性极高，各项信息齐全，可直接用于深度研究"
    elif data_quality_score >= 80:
        quality_level = "良好"
        quality_desc = "数据完整性良好，核心信息齐全，基本满足研究需求"
    elif data_quality_score >= 70:
        quality_level = "中等"
        quality_desc = "数据完整性一般，部分字段存在缺失，建议补充完善"
    else:
        quality_level = "待改进"
        quality_desc = "数据完整性较低，多个关键字段缺失，需要进一步处理"

    print(f"   质量等级: {quality_level}")
    print(f"   评估说明: {quality_desc}")

    stats['quality_score'] = data_quality_score
    stats['quality_level'] = quality_level
    stats['quality_description'] = quality_desc

    print("\n" + "=" * 80)

    return stats


def show_sample_records(data, sample_count=3):
    """
    显示数据样本，帮助用户了解数据结构

    参数:
        data (list): 战争数据列表
        sample_count (int): 显示的样本数量
    """
    if not data:
        return

    print(f"\n📋 数据样本（前{sample_count}条记录）:")
    print("=" * 80)

    for i, record in enumerate(data[:sample_count], 1):
        print(f"\n【样本 {i}】")
        print("-" * 60)

        # 定义要显示的字段及其显示名称
        display_fields = [
            ('category', '历史时期'),
            ('war_name', '战争名称'),
            ('year', '发生年份'),
            ('location', '发生地点'),
            ('parties', '交战双方'),
            ('nature', '战争性质'),
            ('duration', '持续时间'),
            ('source', '文献出处')
        ]

        for field, display_name in display_fields:
            value = record.get(field)
            if value is not None:
                # 特殊处理年份显示
                if field == 'year':
                    value_display = f"公元前{abs(value)}年" if value < 0 else f"{value}年"
                else:
                    value_display = str(value)

                # 控制显示长度
                if len(value_display) > 80:
                    value_display = value_display[:77] + "..."

                print(f"{display_name:8s}: {value_display}")

        # 显示原始描述的前100个字符
        original_desc = record.get('original_description', '')
        if original_desc:
            desc_preview = original_desc[:100] + "..." if len(original_desc) > 100 else original_desc
            print(f"原始描述: {desc_preview}")

    print("\n" + "=" * 80)


def main_single_file_processing(input_file, output_file=None):
    """
    单个Excel文件处理主函数

    参数:
        input_file (str): 输入Excel文件路径
        output_file (str): 输出JSON文件路径，默认为输入文件同目录下的processed.json

    返回:
        dict: 处理结果（包含数据、统计信息等）
    """
    print("\n" + "=" * 80)
    print("🎯 单个战争数据文件处理流程")
    print("=" * 80)

    # 验证输入文件
    if not os.path.exists(input_file):
        print(f"❌ 错误：输入文件不存在 - {input_file}")
        return {'success': False, 'error': '文件不存在'}

    # 处理输出文件路径
    if not output_file:
        input_dir = os.path.dirname(input_file)
        input_filename = os.path.splitext(os.path.basename(input_file))[0]
        output_file = os.path.join(input_dir, f"{input_filename}_processed.json")

    print(f"📥 输入文件: {input_file}")
    print(f"📤 输出文件: {output_file}")

    # 1. 提取数据
    print("\n1. 正在提取战争数据...")
    war_data = extract_war_data_from_excel(input_file, all_sheets=True)

    if not war_data:
        print("❌ 数据提取失败，没有获得有效记录")
        return {'success': False, 'error': '数据提取失败'}

    # 2. 分析数据质量
    print("\n2. 正在分析数据质量...")
    quality_stats = analyze_war_data_quality(war_data)

    # 3. 显示样本数据
    print("\n3. 正在生成数据样本...")
    show_sample_records(war_data, sample_count=3)

    # 4. 保存数据
    print("\n4. 正在保存JSON数据...")
    save_success = save_war_data_to_json(war_data, output_file)

    if save_success:
        print("\n🎉 单个文件处理完成！")
        return {
            'success': True,
            'input_file': input_file,
            'output_file': output_file,
            'record_count': len(war_data),
            'quality_stats': quality_stats,
            'processing_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
    else:
        print("\n❌ 单个文件处理失败（保存环节出错）")
        return {'success': False, 'error': '数据保存失败', 'record_count': len(war_data)}


def main_batch_processing(input_dir, output_dir=None, file_patterns=['战争', '战役', '战事']):
    """
    批量处理文件夹中的所有战争Excel文件

    参数:
        input_dir (str): 输入文件夹路径
        output_dir (str): 输出文件夹路径，默认为input_dir下的war_data_output
        file_patterns (list): 文件名包含的关键词，用于筛选文件

    返回:
        dict: 批量处理统计结果
    """
    print("\n" + "=" * 80)
    print("🎯 战争数据批量处理流程")
    print("=" * 80)

    # 验证输入文件夹
    if not os.path.isdir(input_dir):
        print(f"❌ 错误：输入路径不是有效的文件夹 - {input_dir}")
        return {'success': False, 'error': '无效的输入文件夹'}

    # 处理输出文件夹路径
    if not output_dir:
        output_dir = os.path.join(input_dir, 'war_data_output')

    # 创建输出文件夹
    Path(output_dir).mkdir(parents=True, exist_ok=True)

    print(f"📥 输入文件夹: {input_dir}")
    print(f"📤 输出文件夹: {output_dir}")
    print(f"🔍 文件筛选关键词: {', '.join(file_patterns)}")

    # 统计信息初始化
    batch_stats = {
        'total_files_scanned': 0,
        'total_files_processed': 0,
        'total_files_failed': 0,
        'total_records_extracted': 0,
        'failed_files': [],
        'processed_files': [],
        'batch_start_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'batch_end_time': None,
        'processing_duration': 0
    }

    # 记录开始时间
    start_time = datetime.now()

    # 遍历文件夹中的Excel文件
    print("\n开始扫描并处理文件...")
    print("-" * 80)

    for root, dirs, files in os.walk(input_dir):
        # 跳过输出文件夹，避免重复处理
        if root.startswith(output_dir):
            continue

        for file in files:
            # 筛选Excel文件并且文件名包含指定关键词
            if file.endswith(('.xlsx', '.xls')) and any(pattern in file for pattern in file_patterns):
                file_path = os.path.join(root, file)
                batch_stats['total_files_scanned'] += 1

                print(f"\n📄 正在处理文件 {batch_stats['total_files_scanned']}: {os.path.basename(file_path)}")

                try:
                    # 生成输出文件名
                    file_name_without_ext = os.path.splitext(file)[0]
                    output_file_name = f"{file_name_without_ext}_processed.json"
                    output_file_path = os.path.join(output_dir, output_file_name)

                    # 处理单个文件
                    process_result = main_single_file_processing(file_path, output_file_path)

                    if process_result['success']:
                        batch_stats['total_files_processed'] += 1
                        batch_stats['total_records_extracted'] += process_result['record_count']
                        batch_stats['processed_files'].append({
                            'input_file': file_path,
                            'output_file': output_file_path,
                            'record_count': process_result['record_count']
                        })
                        print(f"✅ 文件处理成功")
                    else:
                        batch_stats['total_files_failed'] += 1
                        batch_stats['failed_files'].append({
                            'file_path': file_path,
                            'error': process_result.get('error', '未知错误')
                        })
                        print(f"❌ 文件处理失败: {process_result.get('error', '未知错误')}")

                except Exception as e:
                    batch_stats['total_files_failed'] += 1
                    batch_stats['failed_files'].append({
                        'file_path': file_path,
                        'error': str(e)
                    })
                    print(f"❌ 文件处理异常: {str(e)}")
                    traceback.print_exc()

    # 计算处理时间
    end_time = datetime.now()
    batch_stats['batch_end_time'] = end_time.strftime('%Y-%m-%d %H:%M:%S')
    batch_stats['processing_duration'] = (end_time - start_time).total_seconds()

    # 生成批量处理报告
    print("\n" + "=" * 80)
    print("📊 批量处理结果汇总报告")
    print("=" * 80)
    print(f"开始时间: {batch_stats['batch_start_time']}")
    print(f"结束时间: {batch_stats['batch_end_time']}")
    print(f"总耗时: {batch_stats['processing_duration']:.2f} 秒")
    print(f"\n文件统计:")
    print(f"  扫描文件总数: {batch_stats['total_files_scanned']} 个")
    print(f"  成功处理: {batch_stats['total_files_processed']} 个")
    print(f"  处理失败: {batch_stats['total_files_failed']} 个")
    print(f"\n数据统计:")
    print(f"  提取记录总数: {batch_stats['total_records_extracted']} 条")

    if batch_stats['failed_files']:
        print(f"\n失败文件列表 ({len(batch_stats['failed_files'])} 个):")
        for i, failed in enumerate(batch_stats['failed_files'], 1):
            print(f"  {i}. {os.path.basename(failed['file_path'])} - {failed['error'][:50]}")

    print("\n" + "=" * 80)

    # 保存批量处理报告
    report_file = os.path.join(output_dir, 'batch_processing_report.json')
    with open(report_file, 'w', encoding='utf-8') as f:
        json.dump(batch_stats, f, ensure_ascii=False, indent=2)

    print(f"📄 批量处理报告已保存到: {report_file}")
    print("🎉 批量处理流程完成！")

    return batch_stats


def main():
    """
    主函数：执行完整的数据处理流程
    采用明确的文件路径配置方式
    """
    # 1. 配置文件路径（默认路径）
    default_input_dir = "./data"  # 默认输入文件夹
    default_output_dir = "./outputs"  # 默认输出文件夹
    default_input_file = "./data/18战争 - 总数据和各朝代数据.xlsx"  # 默认输入文件
    default_output_file = "./outputs/war_data.json"  # 默认输出文件

    print("=" * 80)
    print("🏛️  中国古代战争数据处理系统 (War Data Processing System v1.0)")
    print("=" * 80)
    print("默认文件路径配置:")
    print(f"  输入文件夹: {default_input_dir}")
    print(f"  输出文件夹: {default_output_dir}")
    print(f"  默认输入文件: {default_input_file}")
    print(f"  默认输出文件: {default_output_file}")
    print("=" * 80)

    while True:
        print("\n请选择操作模式:")
        print("  1 - 单个文件处理")
        print("  2 - 批量文件处理")
        print("  3 - 退出程序")

        choice = input("\n请输入选项 (1/2/3): ").strip()

        if choice == '1':
            # 单个文件处理
            print("\n--- 单个文件处理模式 ---")
            use_default = input(f"是否使用默认输入文件? ({default_input_file}) (Y/n): ").strip().lower()

            if use_default in ['n', 'no']:
                input_file = input("请输入Excel文件路径: ").strip()
                # 处理相对路径
                if not os.path.isabs(input_file):
                    input_file = os.path.abspath(input_file)
            else:
                input_file = default_input_file

            # 验证文件存在
            if not os.path.exists(input_file):
                print(f"❌ 错误：文件不存在 - {input_file}")
                # 创建默认数据目录（如果不存在）
                if not os.path.exists(default_input_dir):
                    Path(default_input_dir).mkdir(parents=True, exist_ok=True)
                    print(f"⚠️  已为您创建默认数据目录: {default_input_dir}")
                    print(f"   请将Excel文件放入该目录后重试")
                continue

            # 询问输出路径
            use_default_output = input(f"是否使用默认输出文件? ({default_output_file}) (Y/n): ").strip().lower()
            if use_default_output in ['n', 'no']:
                output_file = input("请输入输出JSON文件路径: ").strip()
                if not os.path.isabs(output_file):
                    output_file = os.path.abspath(output_file)
            else:
                # 确保输出目录存在
                Path(default_output_dir).mkdir(parents=True, exist_ok=True)
                output_file = default_output_file

            # 执行处理
            main_single_file_processing(input_file, output_file)

        elif choice == '2':
            # 批量文件处理
            print("\n--- 批量文件处理模式 ---")
            use_default = input(f"是否使用默认输入文件夹? ({default_input_dir}) (Y/n): ").strip().lower()

            if use_default in ['n', 'no']:
                input_dir = input("请输入文件夹路径: ").strip()
                # 处理相对路径
                if not os.path.isabs(input_dir):
                    input_dir = os.path.abspath(input_dir)
            else:
                input_dir = default_input_dir
                # 确保输入目录存在
                Path(input_dir).mkdir(parents=True, exist_ok=True)

            # 验证文件夹存在
            if not os.path.isdir(input_dir):
                print(f"❌ 错误：文件夹不存在 - {input_dir}")
                continue

            # 询问输出路径
            use_default_output = input(f"是否使用默认输出文件夹? ({default_output_dir}) (Y/n): ").strip().lower()
            if use_default_output in ['n', 'no']:
                output_dir = input("请输入输出文件夹路径: ").strip()
                if not os.path.isabs(output_dir):
                    output_dir = os.path.abspath(output_dir)
            else:
                output_dir = default_output_dir

            # 确保输出目录存在
            Path(output_dir).mkdir(parents=True, exist_ok=True)

            # 执行批量处理
            main_batch_processing(input_dir, output_dir)

        elif choice == '3':
            # 退出程序
            print("\n👋 感谢使用战争数据处理系统，再见！")
            break

        else:
            # 无效选项
            print("❌ 无效选项，请输入 1、2 或 3")

        # 询问是否继续
        continue_processing = input("\n是否继续处理其他文件? (Y/n): ").strip().lower()
        if continue_processing in ['n', 'no']:
            print("\n👋 感谢使用战争数据处理系统，再见！")
            break


# 程序入口
if __name__ == '__main__':
    try:
        # 检查必要的库是否安装
        required_libs = ['pandas', 'openpyxl', 'xlrd']
        missing_libs = []

        for lib in required_libs:
            try:
                __import__(lib)
            except ImportError:
                missing_libs.append(lib)

        if missing_libs:
            print(f"⚠️  检测到缺少必要的Python库: {', '.join(missing_libs)}")
            print(f"   请先安装：pip install {' '.join(missing_libs)}")
        else:
            # 启动主程序
            main()

    except KeyboardInterrupt:
        print("\n\n👋 程序被用户中断，再见！")
    except Exception as e:
        print(f"\n❌ 程序启动出错: {str(e)}")
        traceback.print_exc()